/**
 * lilang
 * WorkCenterServiceImpl.java
 * 2013-10-20下午4:51:05
 */
package com.cq.oa.service.work.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import oa.base.session.SessionManger;
import oa.base.util.Constants;
import oa.base.util.Page;

import com.cq.oa.domain.dto.InstanceDto;
import com.cq.oa.domain.dto.TaskCmd;
import com.cq.oa.domain.dto.WorkDto;
import com.cq.oa.domain.wfc.Activity;
import com.cq.oa.domain.wfc.ActivityInstance;
import com.cq.oa.domain.wfc.ActivityParticipation;
import com.cq.oa.domain.wfc.ProcessDefinition;
import com.cq.oa.domain.wfc.ProcessInstance;
import com.cq.oa.domain.wfc.TaskInstance;
import com.cq.oa.service.util.ProcessUtils;
import com.cq.oa.service.work.ProcessDefinitionService;
import com.cq.oa.service.work.ProcessHisManger;
import com.cq.oa.service.work.ProcessInstanceService;
import com.cq.oa.service.work.WorkCenterService;

/**
 * @author lilang
 *
 */
public class WorkCenterServiceImpl implements WorkCenterService{
	
	/**
	 * 流程定义
	 */
	private ProcessDefinitionService processDefinitionService;
	/**
	 * 流程实例
	 * @return
	 * lilang 
	 * 2013-10-25下午4:17:17
	 */
	private ProcessInstanceService processInstanceService;
	
	
	private ProcessHisManger processHisManger;
	
	
	

	public ProcessHisManger getProcessHisManger() {
		return processHisManger;
	}

	public void setProcessHisManger(ProcessHisManger processHisManger) {
		this.processHisManger = processHisManger;
	}

	public ProcessInstanceService getProcessInstanceService() {
		return processInstanceService;
	}

	public void setProcessInstanceService(
			ProcessInstanceService processInstanceService) {
		this.processInstanceService = processInstanceService;
	}

	public ProcessDefinitionService getProcessDefinitionService() {
		return processDefinitionService;
	}

	public void setProcessDefinitionService(
			ProcessDefinitionService processDefinitionService) {
		this.processDefinitionService = processDefinitionService;
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#getWorkProcessDefinition(java.lang.Long)
	 */
	public WorkDto getWorkProcessDefinition(Long sid) {
		return processDefinitionService.findProcessDefinitionById(sid);
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#doStartWork(java.lang.Long)
	 */
	public InstanceDto doStartWork(Long definitionId,String title) {
		InstanceDto inst = new InstanceDto();
		//start workflow
		WorkDto dto =getWorkProcessDefinition(definitionId);
		ProcessInstance instance = this.processInstanceService.createProcessStart(dto, title);
		inst.setProcessInstanceId(instance.getSid());
		Activity node = dto.getStartNode();
		inst.setActivityId(node.getSid());
		ActivityInstance activityInstance = this.processInstanceService.createActivityInstance(instance, node,1);
		inst.setActivityInstanceId(activityInstance.getSid());
		TaskInstance task =this.processInstanceService.createTask(activityInstance, node,TaskCmd.newInstance(),title);
		inst.setTaskId(task.getSid());
		inst.setBusinessId(instance.getBusinessId());
		return inst;
	}

	

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#getBackActivity(java.lang.Long)
	 */
	public List<Activity> getBackActivity(Long taskId) {
		
		return null;
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#getNextActivity(java.lang.Long)
	 */
	public List<Activity> getNextActivity(Long taskId) {
		TaskInstance instance = processInstanceService.getTaskInstanceDao().get(taskId);
		ActivityInstance activityInstance = processInstanceService.getActivityInstance(instance.getProcessActivitySid());
		WorkDto dto = getWorkProcessDefinition(instance.getProcessDefinitionSid());
		return dto.getNextNodes(activityInstance.getActivitySid());
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#getAllTaskList(java.lang.String)
	 */
	public List<TaskInstance> getAllTaskList(String businessId) {
		Map<String,Object> param = new HashMap<String, Object>();
		param.put(Constants.BUSINESS_ID, businessId);
		return this.processInstanceService.getTaskInstanceDao().find(param);
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#doCompleteTask(java.lang.Long, java.lang.String[])
	 */
	public synchronized void doCompleteTask(Long taskId, List<TaskCmd> nextTask,Long activityId) throws Exception {
		TaskInstance taskInstance = this.processInstanceService.getTaskInstanceDao().get(taskId);
		if(taskInstance==null || ProcessUtils.TASK_END.equals(taskInstance.getTaskStatus())){
			throw new Exception("流程任务不存在或已经完成");
		}
		taskInstance.setEndTime(new Date());
		taskInstance.setTaskStatus(ProcessUtils.TASK_END);
		taskInstance.setOperId(SessionManger.getUserId());
		taskInstance.setOperCname(SessionManger.getCname());
		taskInstance.setOperDeptId(SessionManger.getDeptId());
		taskInstance.setOperDeptCname(SessionManger.getDeptCname());
		//是否整个活动任务都完成
		boolean isActivityTrue = this.processInstanceService.doEndTask(taskInstance);
		WorkDto dto = this.processDefinitionService.findProcessDefinitionById(taskInstance.getProcessDefinitionSid());
		Activity activity = dto.getNode(activityId);
		ProcessInstance processInstance = this.processInstanceService.findByParmkeys(taskInstance.getProcessInstanceSid());
		//如何下面没有任务表示已经是流程结束0
		//表示下一个节点为结束节点
		if("E".equals(activity.getClazz())){
			processInstance.setOperCname("");
			processInstance.setActivityCname("");
			processInstance.setEndTime(new Date());
			processInstance.setProcessStatus(ProcessUtils.PROCESS_END);
			this.processInstanceService.updateSelect(processInstance);
			processHisManger.doBackProcessInstance(taskInstance.getBusinessId());
		}else{
			ActivityInstance activityInstance=this.processInstanceService.createActivityInstance(processInstance, activity,nextTask.size());
			StringBuffer taskCname = new StringBuffer();
			boolean isHiddenTask = this.isHiddenTask(dto.getNode(processInstance.getActivitySid()),activity);
			for(TaskCmd cmd:nextTask){
				taskCname.append(cmd.getTaskCname()+",");
				if(isHiddenTask){
					//创建隐藏任务
					this.processInstanceService.createHiddenTask(activityInstance, activity, cmd,processInstance.getTitle());
				}else{
					this.processInstanceService.createTask(activityInstance, activity, cmd,processInstance.getTitle());
				}
				
			}
			//更新流程实例信息
			processInstance.setActivitySid(activity.getSid());
			processInstance.setActivityCname(activity.getName());
			processInstance.setOperCname(taskCname.toString());
			//上一个任务完成 并且这个任务也是隐藏任务  刷新隐藏任务
			if(isActivityTrue && isHiddenTask){
				this.processInstanceService.doUpdateTaskStatus(activityInstance.getSid());
			}
			this.processInstanceService.updateSelect(processInstance);
		}
	}

	/**
	 * 判断是否创建隐藏任务
	 * @return
	 * lilang 
	 * 2013-11-1上午9:53:56
	 */
	private boolean isHiddenTask(Activity upAct,Activity nextAct){
		//如果 上一步活动是多任务  当前活动也是多任务  那当前任务在 上一步未完成的情况下隐藏任务状态
		if(upAct.getIsMultiTask()==ProcessUtils.MUST_TASK && nextAct.getIsMultiTask()==ProcessUtils.MUST_TASK){
			return true;
		}
		return false;
	}
	
	
	
	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#getActivityParticipation(java.lang.Long)
	 */
	public List<ActivityParticipation> getActivityParticipation(Long activityId) {
		return this.processDefinitionService.findActivityPartion(activityId);
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#updateProcessInfo(java.lang.Long, java.lang.String, java.util.Map)
	 */
	public void updateProcessInfo(Long processId, String title,Map<String, Object> params) {
		ProcessInstance instance = this.processInstanceService.findByParmkeys(processId);
		instance.setTitle(title);
		this.processInstanceService.updateSelect(instance);
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#updateTaskMsg(java.lang.Long, java.lang.String)
	 */
	public void updateTaskMsg(Long taskId, String msg) {
		TaskInstance instance = this.processInstanceService.getTaskInstanceDao().get(taskId);
		instance.setMsg(msg);
		this.processInstanceService.getTaskInstanceDao().updateSelect(instance);
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#getProcess()
	 */
	public List<ProcessDefinition> getProcess() {
		return processDefinitionService.findParByList(new HashMap<String, Object>());
	}

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.WorkCenterService#findTaskByOwn(java.util.Map, int, int)
	 */
	@SuppressWarnings("unchecked")
	public Page<TaskInstance> findTaskByOwn(Map<String, Object> param,int pageNo, int pageSize) {
		return this.processInstanceService.getTaskInstanceDao().pagedQuery(param, new HashMap<String, Object>(), pageNo, pageSize);
	}
	
	

}
